package creatingPattern.abstractFactory;

/**
 * @Author: Alex Hu
 * Date: 2020/2/22 6:24 下午
 * Content:
 */

import javax.swing.*;
import java.awt.*;

/**
 * 抽象工厂模式示例：农场
 * 设计意图：提供一个创建一系列相关或相互依赖对象的接口，而无需指定它们具体的类
 * 使用场景：当需要创建一系列相关产品时，抽象工厂模式可统一产品创建行为
 */
public class FarmTest {
    /**
     * 主方法：演示抽象工厂模式
     * 设计意图：通过XML配置动态创建工厂和产品
     * 使用场景：当需要根据配置创建不同产品时，调用此方法
     * @param args 命令行参数
     */
    public static void main(String[] args) {
        try {
            Farm f;
            Animal a;
            Plant p;
            f = (Farm) ReadXML.getObject();
            a = f.newAnimal();
            p = f.newPlant();
            a.show();
            p.show();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}

/**
 * 动物接口：定义动物的行为
 * 设计意图：定义产品的规范，描述产品的主要特性和功能
 * 使用场景：当需要创建一系列相关产品时，抽象产品接口可统一产品行为
 */
interface Animal {
    /**
     * 显示动物
     * 设计意图：定义动物的展示行为
     * 使用场景：当需要展示动物信息时，调用此方法
     */
    void show();
}

/**
 * 植物接口：定义植物的行为
 * 设计意图：定义产品的规范，描述产品的主要特性和功能
 * 使用场景：当需要创建一系列相关产品时，抽象产品接口可统一产品行为
 */
interface Plant {
    /**
     * 显示植物
     * 设计意图：定义植物的展示行为
     * 使用场景：当需要展示植物信息时，调用此方法
     */
    void show();
}

/**
 * 农场接口：定义创建动物和植物的方法
 * 设计意图：定义创建产品的接口，让子类决定实例化哪个类
 * 使用场景：当需要创建一系列相关产品时，抽象工厂可统一产品创建行为
 */
interface Farm {
    /**
     * 创建动物
     * 设计意图：定义创建动物的抽象方法
     * 使用场景：当需要创建动物时，调用此方法
     * @return 返回创建的动物
     */
    Animal newAnimal();

    /**
     * 创建植物
     * 设计意图：定义创建植物的抽象方法
     * 使用场景：当需要创建植物时，调用此方法
     * @return 返回创建的植物
     */
    Plant newPlant();
}

/**
 * 马类：实现动物接口
 * 设计意图：实现抽象产品接口，提供具体产品行为
 * 使用场景：当需要创建具体产品时，具体产品类可提供具体实现
 */
class Horse implements Animal {
    /**
     * 滚动面板
     * 设计意图：存储滚动面板对象
     * 使用场景：当需要展示马的信息时，使用此字段
     */
    JScrollPane sp;

    /**
     * 窗口
     * 设计意图：存储窗口对象
     * 使用场景：当需要展示马的信息时，使用此字段
     */
    JFrame jf = new JFrame("抽象工厂模式测试");

    /**
     * 构造函数
     * 设计意图：初始化马的信息
     * 使用场景：当需要创建马对象时，调用此构造函数
     */
    public Horse() {
        Container contentPane = jf.getContentPane();
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 1));
        p1.setBorder(BorderFactory.createTitledBorder("动物：马"));
        sp = new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1 = new JLabel(new ImageIcon("src/main/java/creatingPattern/abstractFactory/A_Horse.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        /**用户点击窗口关闭*/
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 显示马
     * 设计意图：实现动物的展示行为
     * 使用场景：当需要展示马的信息时，调用此方法
     */
    public void show() {
        jf.setVisible(true);
    }
}

/**
 * 牛类：实现动物接口
 * 设计意图：实现抽象产品接口，提供具体产品行为
 * 使用场景：当需要创建具体产品时，具体产品类可提供具体实现
 */
class Cattle implements Animal {
    /**
     * 滚动面板
     * 设计意图：存储滚动面板对象
     * 使用场景：当需要展示牛的信息时，使用此字段
     */
    JScrollPane sp;

    /**
     * 窗口
     * 设计意图：存储窗口对象
     * 使用场景：当需要展示牛的信息时，使用此字段
     */
    JFrame jf = new JFrame("抽象工厂模式测试");

    /**
     * 构造函数
     * 设计意图：初始化牛的信息
     * 使用场景：当需要创建牛对象时，调用此构造函数
     */
    public Cattle() {
        Container contentPane = jf.getContentPane();
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 1));
        p1.setBorder(BorderFactory.createTitledBorder("动物：牛"));
        sp = new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1 = new JLabel(new ImageIcon("src/main/java/creatingPattern/abstractFactory/A_Cattle.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        /**用户点击窗口关闭*/
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 显示牛
     * 设计意图：实现动物的展示行为
     * 使用场景：当需要展示牛的信息时，调用此方法
     */
    public void show() {
        jf.setVisible(true);
    }
}

/**
 * 水果类：实现植物接口
 * 设计意图：实现抽象产品接口，提供具体产品行为
 * 使用场景：当需要创建具体产品时，具体产品类可提供具体实现
 */
class Fruitage implements Plant {
    /**
     * 滚动面板
     * 设计意图：存储滚动面板对象
     * 使用场景：当需要展示水果的信息时，使用此字段
     */
    JScrollPane sp;

    /**
     * 窗口
     * 设计意图：存储窗口对象
     * 使用场景：当需要展示水果的信息时，使用此字段
     */
    JFrame jf = new JFrame("抽象工厂模式测试");

    /**
     * 构造函数
     * 设计意图：初始化水果的信息
     * 使用场景：当需要创建水果对象时，调用此构造函数
     */
    public Fruitage() {
        Container contentPane = jf.getContentPane();
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 1));
        p1.setBorder(BorderFactory.createTitledBorder("植物：水果"));
        sp = new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1 = new JLabel(new ImageIcon("src/main/java/creatingPattern.abstractFactory/P_Fruitage.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        /**用户点击窗口关闭*/
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 显示水果
     * 设计意图：实现植物的展示行为
     * 使用场景：当需要展示水果的信息时，调用此方法
     */
    public void show() {
        jf.setVisible(true);
    }
}

/**
 * 蔬菜类：实现植物接口
 * 设计意图：实现抽象产品接口，提供具体产品行为
 * 使用场景：当需要创建具体产品时，具体产品类可提供具体实现
 */
class Vegetables implements Plant {
    /**
     * 滚动面板
     * 设计意图：存储滚动面板对象
     * 使用场景：当需要展示蔬菜的信息时，使用此字段
     */
    JScrollPane sp;

    /**
     * 窗口
     * 设计意图：存储窗口对象
     * 使用场景：当需要展示蔬菜的信息时，使用此字段
     */
    JFrame jf = new JFrame("抽象工厂模式测试");

    /**
     * 构造函数
     * 设计意图：初始化蔬菜的信息
     * 使用场景：当需要创建蔬菜对象时，调用此构造函数
     */
    public Vegetables() {
        Container contentPane = jf.getContentPane();
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(1, 1));
        p1.setBorder(BorderFactory.createTitledBorder("植物：蔬菜"));
        sp = new JScrollPane(p1);
        contentPane.add(sp, BorderLayout.CENTER);
        JLabel l1 = new JLabel(new ImageIcon("src/main/java/creatingPattern/abstractFactory/P_Vegetables.jpg"));
        p1.add(l1);
        jf.pack();
        jf.setVisible(false);
        /**用户点击窗口关闭*/
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    /**
     * 显示蔬菜
     * 设计意图：实现植物的展示行为
     * 使用场景：当需要展示蔬菜的信息时，调用此方法
     */
    public void show() {
        jf.setVisible(true);
    }
}

/**
 * 具体工厂：实现农场接口
 * 设计意图：实现抽象工厂接口，提供具体产品创建行为
 * 使用场景：当需要创建具体产品时，具体工厂类可提供具体实现
 */
class SGfarm implements Farm {
    /**
     * 创建动物
     * 设计意图：实现创建动物的抽象方法
     * 使用场景：当需要创建动物时，调用此方法
     * @return 返回创建的动物
     */
    public Animal newAnimal() {
        System.out.println("新牛出生！");
        return new Cattle();
    }

    /**
     * 创建植物
     * 设计意图：实现创建植物的抽象方法
     * 使用场景：当需要创建植物时，调用此方法
     * @return 返回创建的植物
     */
    public Plant newPlant() {
        System.out.println("蔬菜长成！");
        return new Vegetables();
    }
}

/**
 * 具体工厂：实现农场接口
 * 设计意图：实现抽象工厂接口，提供具体产品创建行为
 * 使用场景：当需要创建具体产品时，具体工厂类可提供具体实现
 */
class SRfarm implements Farm {
    /**
     * 创建动物
     * 设计意图：实现创建动物的抽象方法
     * 使用场景：当需要创建动物时，调用此方法
     * @return 返回创建的动物
     */
    public Animal newAnimal() {
        System.out.println("新马出生！");
        return new Horse();
    }

    /**
     * 创建植物
     * 设计意图：实现创建植物的抽象方法
     * 使用场景：当需要创建植物时，调用此方法
     * @return 返回创建的植物
     */
    public Plant newPlant() {
        System.out.println("水果长成！");
        return new Fruitage();
    }
}
